﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IPMocanu
{
    class Program
    {
        

        

        abstract class Masina 
        {
            private string transmisie;
            private string culoare;

            public void setTransmisie(string t)
            {
                transmisie = t;
            }

            public void setCuloare(string c)
            {
                culoare = c;
            }

            public string getTransmisie()
            {
                return transmisie;

            }

            public string getCuloare()
            {
                return culoare;

            }

            public abstract string getDimensiuni();
            public abstract string getDotari();
            public abstract string getMotorizare();
            public virtual void setDimensiuni(string str) { }
            public virtual void setDotari(string str) { }
            public virtual void setMotorizare(string str) { }
        }

        class Coupe : Masina
        {
            private string dotari;
            private string motorizare;
            private string dimensiuni;

            public override void setDotari(string d)
            {
                dotari = d;
            }

            public override void setMotorizare(string m)
            {
                motorizare = m;
            }

            public override void setDimensiuni(string di)
            {
                dimensiuni = di;
            }
            public override string getDotari()
            {
                return dotari;

            }

            public override string getMotorizare()
            {
                return motorizare;

            }

            public override string getDimensiuni()
            {
                return dimensiuni;

            }
        }

        class Mini : Masina
        {
            private string dotari;
            private string motorizare;
            private string dimensiuni;

            public override void setDotari(string d)
            {
                dotari = d;
            }

            public override void setMotorizare(string mo)
            {
                motorizare = mo;
            }

            public override void setDimensiuni(string di)
            {
                dimensiuni = di;
            }
            public override string getDotari()
            {
                return dotari;

            }

            public override string getMotorizare()
            {
                return motorizare;

            }

            public override string getDimensiuni()
            {
                return dimensiuni;

            }
        }

        class Sedan: Masina
        {
            private string dotari;
            private string motorizare;
            private string dimensiuni;

            public override void setDotari(string d)
            {
                dotari = d;
            }

            public override void setMotorizare(string mo)
            {
                motorizare = mo;
            }

            public override void setDimensiuni(string di)
            {
                dimensiuni = di;
            }
            public override string getDotari()
            {
                return dotari;

            }

            public override string getMotorizare()
            {
                return motorizare;

            }

            public override string getDimensiuni()
            {
                return dimensiuni;

            }
        }
       
        abstract class AbstractFactory
        {
            public abstract Masina createProduct();
        }

       
        class FabricaCoupe : AbstractFactory
        {
            public override Masina createProduct()
            {
                return new Coupe();
            }
        }

        class FabricaMini : AbstractFactory
        {
            public override Masina createProduct()
            {
                return new Mini();
            }
        }

        class FabricaSedan : AbstractFactory
        {
            public override Masina createProduct()
            {
                return new Sedan();
            }
        }

        class Client
        {
            private string nume;
            private string varsta;
            private List<Masina> lista = new List<Masina>();
            private static int nrClienti = 0;



            public static void adaugaClient()
            {
                nrClienti++;
            }
            public static void stergeClient()
            {
                nrClienti--;

            }
            public static int afisazaNrClienti()
            {
                return nrClienti;
            }
            public void setNume(string n)
            {
                nume = n;
            }

            public void setVarsta(string v)
            {
                varsta = v;
            }

            public string getNume()
            {
                return nume;
            }

            public string getVarsta()
            {
                return varsta;
            }

            public void adaugaMasina(Masina masina)
            {
                if (!lista.Contains(masina))
                {
                    lista.Add(masina);
                }

            }



            public void afisazaMasini()
            {
                foreach (Masina masina in lista)
                {

                                  

                    Console.WriteLine("Culoare: " + masina.getCuloare());


                    Console.WriteLine("Transmisie: " + masina.getTransmisie());


                    Console.WriteLine("Motorizare: " + masina.getMotorizare());

                    Console.WriteLine("Dimensiuni: " + masina.getDimensiuni());


                    Console.WriteLine("Dotari: " + masina.getDotari());

                                    }
            }
        }

        class cPool
        {

            private static readonly List<Client> pool = new List<Client>(30);
            private static cPool instance;
            public static cPool Instance
            {
                get
                {
                    if (instance == null)
                    {
                        instance = new cPool();
                    }
                    return instance;
                }
            }
            public Client ext(string nume, string varsta)
            {
                Client obj = null;


                if (Client.afisazaNrClienti() >= 30 && pool.Count > 0)
                {
                    int found = 0;
                    foreach (Client c in pool)
                    {
                        if (c.getNume() == nume && c.getVarsta() == varsta)
                        {

                            obj = c;
                            Client.adaugaClient();
                            
                            found = 1;
                            return obj;
                        }
                    }
                    if (found == 0) obj = nou(nume, varsta);
                }
                else
                {
                    obj = nou(nume, varsta);
                }
                return obj;
            }

            private Client nou(string nume, string varsta)
            {

                Client nObj = new Client();
                nObj.setNume(nume);
                nObj.setVarsta(varsta);
                pool.Add(nObj);
                return nObj;
            }
        }
        
        static void Main(string[] args)
        {
            Console.WriteLine("Introdu client(0/1)");
            string ok = Console.ReadLine();

            while (ok == "1")
            {
                Console.WriteLine("Informatii");

                Console.WriteLine("__NUME:");
                string nume = Console.ReadLine();

                Console.WriteLine("__VARSTA:");
                string varsta = Console.ReadLine();

                Client client = cPool.Instance.ext(nume, varsta);

                Console.WriteLine(" ");

                Console.WriteLine("Introdu masina(0/1)");
                string ok2 = Console.ReadLine();

                while (ok2 == "1")
                {

                    Console.WriteLine("Configureaza-ti masina.");

                    Console.WriteLine("______TRANSMISIE_______");
                    string transmisie = Console.ReadLine();

                    Console.WriteLine("______CULOARE__________");
                    string culoare = Console.ReadLine();

                    Console.WriteLine("_______TIP____________");
                    Console.WriteLine("__SE / MI / CO__");
                    string tip = Console.ReadLine();

                    Console.WriteLine("______DOTARI__________");
                    string dotari;
                    dotari = Console.ReadLine();

                    Console.WriteLine("______DIMENSIUNI______");
                    string dimensiuni;
                    dimensiuni = Console.ReadLine();

                    Console.WriteLine("______MOTORIZARE______");
                    string motorizare;
                    motorizare = Console.ReadLine();

                    Console.WriteLine(" ");

                    AbstractFactory fact;

                    
                    if (tip == "SE")
                    {
                        
                        fact = new FabricaSedan();

                        Sedan masina1 = (Sedan)fact.createProduct();

                        masina1.setCuloare(culoare);
                        masina1.setDimensiuni(dimensiuni);
                        masina1.setDotari(dotari);
                        masina1.setMotorizare(motorizare);
                        masina1.setTransmisie(transmisie);

                        client.adaugaMasina(masina1);

                    }
                    else
                        if (tip == "CO")
                        {
                            
                            fact = new FabricaCoupe();

                            Coupe masina2 = (Coupe)fact.createProduct();

                            masina2.setCuloare(culoare);
                            masina2.setDimensiuni(dimensiuni);
                            masina2.setDotari(dotari);
                            masina2.setMotorizare(motorizare);
                            masina2.setTransmisie(transmisie);

                            client.adaugaMasina(masina2);
                        }
                        else
                            if (tip == "MI")
                            {
                                
                                fact = new FabricaMini();

                                Mini masina3 = (Mini)fact.createProduct();

                                masina3.setCuloare(culoare);
                                masina3.setDimensiuni(dimensiuni);
                                masina3.setDotari(dotari);
                                masina3.setMotorizare(motorizare);
                                masina3.setTransmisie(transmisie);

                                client.adaugaMasina(masina3);
                            }

                  
                    Console.WriteLine(" ");

                    Console.WriteLine("Adauga alta masina? (0/1):");
                    ok2 = Console.ReadLine();

                }

                Console.WriteLine("=======================================");

                Console.WriteLine("Afisaza masini(0/1):");
                string afisazaMasini = Console.ReadLine();
                if (afisazaMasini == "1")
                {
                    client.afisazaMasini();
                }

                Console.WriteLine(" ");
                Console.WriteLine("Adauga un nou client(0/1)");
                ok = Console.ReadLine();
            }


        }
    }
}
